#!/bin/zsh

# 目录----------------------------------------------------------------------目录

### - zsh配置
### - 变量
### - 环境变量
### - 自定义函数
### - 自动加载
### - 插件配置（zsh插件、第三方命令行软件配置
###     - oh-my-zsh
###     - fzf
###     - z.lu
###     - autojump
### - 自定义命令
### - 热键绑定

#---------------------------------------目录-----------------------------------


# zsh 配置--------------------------------------------------------------zsh 配置
DISABLE_AUTO_UPDATE="true" # 关闭每天会在第一次打开时进行自动更新检测（需要开启时注释掉）
plugins=(
  git
  vi-mode
  zsh-autosuggestions
  zsh-history-substring-search
  zsh-syntax-highlighting
  zsh-interactive-cd
  web-search
  zoxide
  fzf
  fzf-tab
  z
  tmux
  tig
  universalarchive
  thefuck
)

# plugins=(
#   git
#   vi-mode
#   fzf
#   z
# )

# 其他插件
  # web-search
  # zoxide
#-------------------------------------zsh 配置----------------------------------



# 变量-----------------------------------------------------------------------变量
# glabal_github_proxy_url="https://github.moeyy.xyz/"
# glabal_github_proxy_url="https://gitapi.simplehac.top/"
glabal_github_proxy_url=""  # github代理

TEST_MODE="false" # 开启打印模式 true 开始  false 关闭
shellfilepath="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

#-------------------------------------变量---------------------------------------



# 环境变量------------------------------------------------------------------环境变量

### - 应用执行文件目录
export PATH=/opt/local/bin:$PATH
export PATH=/opt/local/sbin:$PATH

# 解决zsh:zsh: command not found fzf:
export PATH=$HOME/.local/bin:$PATH
# export PATH=$HOME/bin:$PATH
# export PATH=$HOME/Tools:$PATH

export PATH=$HOME/.cargo/bin:$PATH  # 解决 cargo 安装的软件找不到

# [git-remote-gcrypt](https://git.spwhitton.name/git-remote-gcrypt)
# 添加以下环境变量在你的cli：(否则会出错)
export GPG_TTY=$(tty)
# export PATH=$GPG_TTY:$PATH:.
export PATH=$GPG_TTY:$PATH:.

# git使用vim
# git config --global core.editor "vim"
export GIT_EDITOR=vim
export VISUAL=vim
export EDITOR="VISUAL"

### - Java
# export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
if [ -e "$JAVA_HOME" ]; then
    export PATH=$JAVA_HOME/bin:$PATH:.
    export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.
    export JAVA_HOME
fi

### - Python
PY_VERSION=`python -V 2>&1|awk '{print $2}'|awk -F '.' '{print $1"."$2}'`
# PY_VERSION=`python3 -V 2>&1|awk '{print $2}'|awk -F '.' '{print $1"."$2}'`
# export PATH=${PATH}:$HOME/Library/Python/$PY_VERSION/lib/python/site-packages
# export PATH=${PATH}:/Library/Python/$PY_VERSION/site-packages
PYTHON_HOME=$HOME/Library/Python/$PY_VERSION/bin
if [ -e "$PYTHON_HOME" ]; then
    export PATH=${PATH}:$PYTHON_HOME
fi

PYENV_ROOT="$HOME/.pyenv"
if [ -e "$PYENV_ROOT" ]; then
    export PATH="$PYENV_ROOT/bin:$PATH"
    export PATH="$PYENV_ROOT/shims:$PATH"
    export PYENV_ROOT
fi
# eval "$(pyenv init -)"
# eval "$(pyenv virtualenv-init -)"

### - HBuilderX
# 添加HBuilderX的cli命令
HX_HOME=/Applications/HBuilderX.app/Contents/MacOS/
if [ -e "$HX_HOME" ]; then
    export HX_HOME=/Applications/HBuilderX.app/Contents/MacOS/
    export PATH=$HX_HOME:$PATH:.
fi

### - calibre
# 添加calibre（电子书）命令行工具
# export CAKLIBRE_HOME="/Applications/calibre.app/Contents/console.app/Contents/MacOS"
CAKLIBRE_HOME="/Applications/calibre.app/Contents/MacOS"
if [ -e "$CAKLIBRE_HOME" ]; then
    export PATH=$CAKLIBRE_HOME:$PATH:.
    export CAKLIBRE_HOME
fi

### - nvm
# node版本管理器nvm
NVM_DIR="$HOME/.nvm"
if [ -e "$NVM_DIR" ]; then
    export NVM_DIR
    [ -s "/usr/local/opt/nvm/nvm.sh" ] && \. "/usr/local/opt/nvm/nvm.sh"  # This loads nvm
    [ -s "/usr/local/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/usr/local/opt/nvm/etc/bash_completion.d/nvm"  # This loads nvm bash_completion
fi

### - npm
# export PATH=~/.npm-global/bin:${PATH}:/usr/local/bin

### -john
john_jumbo="/usr/local/Cellar/john-jumbo/1.9.0_1/share/john"
if [ -e "$john_jumbo" ]; then
    # export PATH="/usr/local/Cellar/john-jumbo/1.9.0_1/share/john:$PATH"
    export PATH=$john_jumbo:$PATH
fi

### - ruby
# If you need to have ruby first in your PATH run:
#   echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc
# For compilers to find ruby you may need to set:
#   export LDFLAGS="-L/usr/local/opt/ruby/lib"
#   export CPPFLAGS="-I/usr/local/opt/ruby/include"
RUBY_HOME=/usr/local/opt/ruby/bin
if [ -e "$RUBY_HOME" ]; then
    export PATH=$RUBY_HOME:$PATH
fi

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$($HOME'/anaconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then
        . "$HOME/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="$HOME/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# Anaconda安装的包所在默认的位置
# anaconda安装的位置\envs\虚拟环境\Lib\site-packages
# 例：（base） ~/anaconda3/envs/py310/lib
#             ~/anaconda3/lib/python3.11/site-packages

# <<< conda initialize <<<

#-------------------------------------环境变量------------------------------------
# 自定义函数-------------------------------------------------------------自定义函数

### 日志函数
function xecho() {
    local flag="$1"
    local message="$2"
    local timestamp=$(date +"%T")
    local color_code=""
    case "$flag" in
        INFO)    color_code="\033[0;37m" ;;
        Info)    color_code="\033[0;32m" ;;
        WARNING) color_code="\033[0;33m" ;;
        DEBUG)   color_code="\033[0;34m" ;;
        Debug)   color_code="\033[0;34m" ;;
        debug)   color_code="\033[0;34m" ;;
        ERROR)   color_code="\033[0;31m" ;;
        SUCCESS) color_code="\033[0;32m" ;;
        *)       color_code="\033[0m"    ;;
    esac
    
    if [[ "$TEST_MODE" == "true" ]]; then
        echo -e "${color_code}[$flag][$timestamp] $message\033[0m"
    elif [[ "$flag" == "ERROR" || "$flag" == "INFO" || "$flag" == "Info" || "$flag" == "WARNING" ||"$flag" == "SUCCESS"  ]]; then
        echo -e "${color_code}[$flag][$timestamp] $message\033[0m"
    fi
}
# 纯Bash实现获取真实路径
# get_real_path() {
#     local target_file="$1"
    
#     # 尝试使用 readlink -f (Linux)
#     if readlink -f "$target_file" >/dev/null 2>&1; then
#         readlink -f "$target_file"
#     # 尝试使用 greadlink (MacOS with Homebrew coreutils)
#     elif command -v greadlink >/dev/null 2>&1; then
#         greadlink -f "$target_file"
#     # 使用Python作为后备方案
#     else
#         python -c "import os; print(os.path.realpath('$target_file'))"
#     fi
# }

### 安全执行安装命令
function xeval(){
    local cmd="$1"
    xecho "DEBUG" "执行命令：$cmd"
    if declare -f "${cmd%% *}" > /dev/null; then # 这条命令检查 ${cmd%% *}（即命令字符串的第一个单词）是否是一个已定义的函数：
        $cmd
    else
        eval "$cmd"
    fi
}

### 加载
function source_config(){
    file_path="$1"
    local expanded_file_path="${file_path/#\~/$HOME}" # 将开头的波浪号 ~ 替换为 $HOME 的实际值
    xecho "DEBUG" "$file_path =>$expanded_file_path"
    if [ -f "$expanded_file_path" ] ; then
        xecho "DEBUG" "$expanded_file_path 加入环境变量"
        source $expanded_file_path >/dev/null 2>&1 || true;
    elif [ -d "$expanded_file_path" ] ; then
        xecho "DEBUG" "$expanded_file_path 加入环境变量"
        export PATH="$expanded_file_path:$PATH"
    fi 
}

### 自动加载 zsh插件
function auto_zsh_plugin_config(){
  zsh_plugin_fa="$1"
  zsh_plugin_name="$2"
  zsh_plugin_save_path="$HOME/.oh-my-zsh/custom/plugins/${zsh_plugin_name}"
  xecho "DEBUG" "zsh_plugin_save_path =$zsh_plugin_save_path"
  if [ ! -d ${zsh_plugin_save_path} ]; then
      xeval "git clone --depth=1 ${glabal_github_proxy_url}https://github.com/${zsh_plugin_fa}/${zsh_plugin_name}  ${zsh_plugin_save_path}"
  fi
}

function auto_zinit_plugin_config(){
  zinit_plugin_fa="$1"
  zinit_plugin_name="$2"
  zinit_plugin_save_path="$HOME/.zi/plugins/${zinit_plugin_fa}---${zinit_plugin_name}"
  xecho "DEBUG" "zsh_plugin_save_path =$zinit_plugin_save_path"
  if [ ! -d ${zinit_plugin_save_path} ]; then
      xeval "git clone --depth=1 ${glabal_github_proxy_url}https://github.com/${zinit_plugin_fa}/${zinit_plugin_name}  ${zinit_plugin_save_path}"
  fi
}

## 判断文件是否为软链接并获取路径的函数
check_symlink() {
    local file_path="$1"
    # 检查文件是否存在
    if [ ! -e "$file_path" ]; then
        xecho “ERROR” "文件 '$file_path' 不存在"
        return 1
    fi
    
    # 判断是否为软链接
    if [ -L "$file_path" ]; then
        xecho "DEBUG" "文件 $file_path 是一个软链接"
        # 获取软链接指向的目标路径
        target_path=$(readlink "$file_path")
        xecho "DEBUG" "软链接指向: $target_path"
    else
        xecho "DEBUG" "$file_path 不是一个软链接"
        target_path=$file_path
    fi

    # 获取绝对路径（解析相对路径）
    if [ "${target_path:0:1}" != "/" ]; then # 如果是相对路径，转换为绝对路径
        link_dir=$(dirname "$file_path")
        xecho "DEBUG" "link_dir=$link_dir"
        absolute_target=$(cd "$link_dir" && cd "$(dirname "$target_path")" && pwd)/$(basename "$target_path")
        xecho "DEBUG" "绝对路径: $absolute_target"
    else
        absolute_target=$target_path
        xecho "DEBUG" "绝对路径: $target_path"
    fi
    echo "$absolute_target"
}

#----------------------------------自定义函数-------------------------------------



# 自动加载-----------------------------------------------------------------自动加载

xecho "DEBUG" "shellfilepath=${shellfilepath}"
# xecho "DEBUG" "\$0=$0"
# xecho "DEBUG" "\$1=$1"
# zshrc_real_path=$(check_symlink "$0" |tail -n 1) # 获取zshrc的真实地址
# xecho "DEBUG" "zshrc_real_path=${zshrc_real_path}"
zshrc_real_path=$(check_symlink "$HOME/.zshrc" |tail -n 1) # 获取zshrc的真实地址
xecho "DEBUG" "zshrc_real_path=${zshrc_real_path}"
parent_dir=$(dirname "$zshrc_real_path")
xecho "DEBUG" "parent_dir =$parent_dir"
scripts_root_path=$(dirname "$parent_dir")
xecho "DEBUG" "scripts_root_path =$scripts_root_path"
source_config "$scripts_root_path/scripts/bin"

# [ -f ~/.config/lf/icons ] && source ~/.config/lf/icons
source_config "~/.config/lf/icons" # lf图标载入
source_config "~/.nvm/nvm.sh"
# [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
# source_config "~/.fzf.zsh" # fzf脚本载入

# source_config "~/.oh-my-zsh/custom/plugins/fzf-tab/fzf-tab.plugin.zsh"
# source_config "~/.oh-my-zsh/custom/plugins/fzf-tab/fzf-tab.zsh"

#-----------------------------------自动加载--------------------------------------



# 插件配置-----------------------------------------------------------------插件配置

### oh-my-zsh -------------------------------------------------------- oh-my-zsh 
# 检查与安装 oh-my-zsh 
OHMYZSH="$HOME/.oh-my-zsh"
if [ ! -d "$OHMYZSH" ]; then
    URL="${glabal_github_proxy_url}https://github.com/robbyrussell/oh-my-zsh.git"
    if [ -x "$(which git)" ]; then
        xeval  "git clone --depth 1 $URL $OHMYZSH"
    else
        xecho "ERROR" "Please install git  before installation !!"
        exit
    fi
    if [ ! $? -eq 0 ]; then
        xecho "ERROR" "Downloading oh-my-zsh ($URL) failed !!"
        exit
    fi;
fi
export ZSH="${HOME}/.oh-my-zsh"
source_config $ZSH/oh-my-zsh.sh
# # 自动补全
# if [[ ! -f "${OHMYZSH}/custom/plugins/incr/incr.plugin.zsh" ]]; then
#     if [[ ! -d "${OHMYZSH}/custom/plugins/incr" ]]; then
#         mkdir "${OHMYZSH}/custom/plugins/incr"
#     fi
#     if [[ ! -x "$(which wget)" ]]; then
#         echo "[INFO] wget https://mimosa-pudica.net/src/incr-0.2.zsh -O ~/.oh-my-zsh/custom/plugins/incr/incr.plugin.zsh"
#         wget https://mimosa-pudica.net/src/incr-0.2.zsh -O ~/.oh-my-zsh/custom/plugins/incr/incr.plugin.zsh
#     else
#         echo "[INFO] curl -R -O https://mimosa-pudica.net/src/incr-0.2.zsh ; mv ./incr-0.2.zsh ~/.oh-my-zsh/custom/plugins/incr/incr.plugin.zsh "
#         curl -R -O https://mimosa-pudica.net/src/incr-0.2.zsh
#         mv ./incr-0.2.zsh ${OHMYZSH}/custom/plugins/incr/incr.plugin.zsh
#     fi
# else
#     source "${OHMYZSH}/custom/plugins/incr/incr.plugin.zsh"
# fi
# ZSH_THEME="clean" # set by `omz` #主题
auto_zsh_plugin_config "zsh-users" "zsh-autosuggestions" # 安装zsh插件 
auto_zsh_plugin_config "zsh-users" "zsh-history-substring-search"
auto_zsh_plugin_config "zsh-users" "zsh-syntax-highlighting"
auto_zsh_plugin_config "Aloxaf" "fzf-tab"
# auto_zsh_plugin_config "zdharma" "fast-syntax-highlighting"

# 自定义主题
# PROMPT='%{%F{green}%}%n@%m:%{%F{blue}%}%~%{%f%} $ ' #PROMPT 显示为 user@host:~/current/dir $，用户名和主机名是绿色，路径是蓝色。
# RPROMPT='[%*]'  # RPROMPT 在右侧显示当前时间。

# python --version
# 确保 vcs_info 功能开启
autoload -Uz vcs_info
precmd_vcs_info() { vcs_info }
precmd_functions+=( precmd_vcs_info )
setopt prompt_subst
# 启用 Git
zstyle ':vcs_info:*' enable git
# 启用更改检查
zstyle ':vcs_info:git:*' check-for-changes true
# 设置更改指示器字符串
zstyle ':vcs_info:git:*' unstagedstr '!'  # 未暂存更改
zstyle ':vcs_info:git:*' stagedstr '+'    # 已暂存更改
# 设置格式
# %u - 替换为 unstagedstr
# %c - 替换为 stagedstr
zstyle ':vcs_info:git:*' formats '(%b%u%c)'
zstyle ':vcs_info:git:*' actionformats '(%b|%a%u%c)'

# PYTHON_VERSION=`python --version 2>&1|awk '{print $2}'|awk -F '.' '{print $1"."$2"."$2}'`
# env_info_str="[$SHELL]"
env_info_str=""
if command -v "python" &> /dev/null; then
    # PYTHON_VERSION=`python -V 2>&1|awk '{print $2}'|awk -F '.' '{print $1"."$2"."$3}'`
    python_version=`python -V 2>&1|awk '{print $2}'`
    env_info_str+="[${python_version}]"
fi
if command -v "node" &> /dev/null; then
    node_version=`node -v 2>&1`
    env_info_str+="[${node_version}]"
fi
# PROMPT='%F{blue}%}${env_info_str}%f %F{yellow%}%n%f:%~%F{green}%}${vcs_info_msg_0_}%f'$'\n''%# '
# PROMPT='%F{yellow%}%n%f \
# %F{blue}%}${env_info_str}%f \
# %~\
# %F{green}%}${vcs_info_msg_0_}%f\
# '$'\n'\
# '%# '
PROMPT='%F{yellow%}%n%f \
%F{blue}%}${env_info_str}%f \
%F{red}%}%~%f \
%F{green}%}${vcs_info_msg_0_}%f \
'$'\n'\
'%! %# '\
'%F{yellow}%}>%f '
# RPROMPT='[%T]'  # RPROMPT 在右侧显示当前时间。
RPROMPT=''  # RPROMPT 在右侧显示当前时间。

# %n	用户名
# %m	主机名（短）
# %M	主机名（长）
# %~	当前目录（如果是家目录会显示为 ~）
# %d 或 %/	当前目录的绝对路径
# %T	系统时间（24小时制）
# %*	系统时间（带秒的24小时制）
# %!	命令的历史编号
# %#	用户权限提示符（# 表示 root，% 表示普通用户）
# %F{color} / %f	开始/结束颜色设置
# %B / %b	开始/结束粗体
# %U / %u	开始/结束下划线
# %{%F{red}%}	设置红色前景色（可以嵌套）
# 换行符 使用字面换行符（在引号内直接换行)

###--------------------------------oh-my-zsh------------------------------------

### zinit ---------------------------------------------------------------- zinit 
# ZINT_PATH="$HOME/.zinit/bin"
# if [ ! -d "$ZINT_PATH" ]; then
#     ZINT_URL="${glabal_github_proxy_url}https://github.com/zdharma/zinit.git"
#     if [ -x "$(which git)" ]; then
#         xeval  "git clone --depth 1 $ZINT_URL $ZINT_PATH"
#     else
#         xecho "ERROR" "Please install git  before installation !!"
#         exit
#     fi
#     if [ ! $? -eq 0 ]; then
#         xecho "ERROR" "Downloading oh-my-zsh ($ZINT_URL) failed !!"
#         exit
#     fi;
# fi
# source_config "~/.zinit/bin/zi.zsh"
# # auto_zinit_plugin_config "Aloxaf" "fzf-tab"
# # auto_zinit_plugin_config "zsh-users" "zsh-autosuggestions"
# # auto_zinit_plugin_config "zsh-users" "zsh-history-substring-search"
# # auto_zinit_plugin_config "zdharma" "fast-syntax-highlighting"
# autoload -Uz compinit; compinit # zinit 用户这里可能是 zpcompinit; zpcdreplay
# zinit light Aloxaf/fzf-tab      # fzf-tab 放在中间加载
# zinit light zsh-users/zsh-autosuggestions    # 然后再是自动建议和语法高亮
# # zinit light zsh-users/zsh-history-substring-search    # 然后再是自动建议和语法高亮
# zinit light zdharma/fast-syntax-highlighting

###----------------------------------zinit--------------------------------------

### fzf --------------------------------------------------------------------- fzf 
export FZF_DEFAULT_OPTS="--layout=reverse --inline-info \
                        --height=100% \
                        --header='[tab:复制][Shift-tab:多选][ctrl-w:预览窗位置]' \
                        --header-first \
                        --preview-window="hidden:wrap" \
                        --bind='ctrl-w:change-preview-window(down|right|up|)' \
                        --bind='tab:execute( echo {}  | pbcopy )+abort' \
                        --cycle \
                        --preview 'bash $HOME/.config/scripts/preview/file_preview.sh {}'"
if [[ -x "$(which fd)" ]]; then
    ### - 设置使用fd 来查找文件, 并排除了一些项目, 让模糊查找的时候不包括这些项目.
    # export FZF_DEFAULT_COMMAND="fd --exclude={.git,.idea,.vscode,.sass-cache,node_modules,build,dist,vendor} --type f"
    export FZF_DEFAULT_COMMAND="fd --hidden --strip-cwd-prefix --exclude .git"
    export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
    export FZF_ALT_C_COMMAND="fd --type=d --hidden --strip-cwd-prefix --exclude .git"
    _fzf_compgen_path(){
      fd --hidden --exclude .git . "$1"
    }
    _fzf_compgen_dir(){
      fd --type=d --hidden --exclude .git . "$1"
    }
fi
export FZF_PREVIEW_COMMAND='bash $HOME/.config/scripts/preview/file_preview.sh {}'
_fzf_comprun() {
  local command=$1
  shift
  if [ -x  "$(which eza)" ]; then
    #statements
    case "$command" in
      cd)           fzf  --preview-window="right"  --preview 'eza --tree --color=always {} | head -200' "$@" ;;
      export|unset) fzf  --preview "eza 'echo \$' {}" "$@" ;;
      ssh)          fzf  --preview "dig' {}" "$@" ;;
      *)            fzf "$@" ;;
    esac
  elif [ -x  "$(which tree)" ]; then
    case "$command" in
      cd)           fzf "$@" --preview-window="right"  --preview 'tree -C {} | head -200' ;;
      export|unset) fzf  --preview "eza 'echo \$' {}" "$@" ;;
      ssh)          fzf  --preview "dig' {}" "$@" ;;
      *)            fzf "$@" ;;
    esac
  else
    case "$command" in
      cd)           fzf "$@" --preview-window="right"  --preview 'ls {} | head -200' ;;
      ssh)          fzf  --preview "dig' {}" "$@" ;;
      *)            fzf "$@" ;;
    esac
  fi
}
# FZF快捷键 
# CTRL-R : 从历史记录中将所选命令粘贴到命令行上
# CTRL-T: 将选定的文件或者目录粘贴到命令行上
# ALT-C cd进入所选目录
# 可通过设置FZF_CTRL_T_COMMAND覆盖默认命令；
# 可通过设置FZF_CTRL_T_OPTS设置其他选项；
# 可通过设置FZF_ALT_C_COMMAND以覆盖默认命令；
# 可通过设置FZF_ALT_C_OPTS设置其他选项；
### -----------------------------------fzf---------------------------------------

### z.lua ---------------------------------------------------------------- z.lua 
ZLUA="$HOME/.config/z.lua"
if [ ! -d "$ZLUA" ]; then
    # xecho "INFO" "Installing ..."
    URL="${glabal_github_proxy_url}https://github.com/skywind3000/z.lua"
    if [ -x "$(which git)" ]; then
        # xecho "INFO" "git 克隆 URL 到 ($ZLUA)"
        xeval "git clone --depth 1 $URL $ZLUA"
    else
        xecho "ERROR" "Please install git  before installation !!"
        exit
    fi
    if [ ! $? -eq 0 ]; then
        xecho "ERROR" "Downloading  ($URL) failed !!"
        exit
    fi
fi

### ZSH 初始化
eval "$(lua ~/.config/z.lua/z.lua --init zsh enhanced once echo)" 
# - 设置 `$_ZL_CMD` 来改变命令名称 (默认为 z)。
# - 设置 `$_ZL_DATA` 来改变数据文件 (default ~/.zlua)。
# - 设置 `$_ZL_NO_PROMPT_COMMAND` 为 1 来跳过钩子函数初始化（方便自己处理）。
# - 设置 `$_ZL_EXCLUDE_DIRS` 逗号分隔的路径列表，列表内的路径不会被收集。
# - 设置 `$_ZL_ADD_ONCE` 为 '1' 时，仅在当前路径 `$PWD` 改变时才更新数据库。
# - 设置 `$_ZL_MAXAGE` 来确定一个数据老化的阀值 (默认为 5000)。
# - 设置 `$_ZL_CD` 用来指定你想用的 cd 命令，比如有人用 cd_func 。
# - 设置 `$_ZL_ECHO` 为 1 可以在跳转后显示目标路径名称。
# - 设置 `$_ZL_MATCH_MODE` 为 1 可以打开 “增强匹配模式”。
# - 设置 `$_ZL_HYPHEN` 为 1 可以允许关键字中包含横线 （横线默认是 lua 正则关键字，要转写成 `%-`）。
alias zh='z -I -t .'   # 回到历史路径，用 fzf 进行历史路径操作
alias zi='z -i'        # 使用交互式选择模式
alias zf='z -I'        # 使用 fzf 对多个结果进行选择
alias zb='z -b'        # 快速回到父目录

### -------------------------------z.lua ---------------------------------------

### autojump ----------------------------------------------------------- autojump
source_config "/usr/local/etc/profile.d/autojump.sh"
### ---------------------------- autojump ---------------------------------------

### starship ----------------------------------------------------------- starship
# # [配置 | Starship](https://starship.rs/zh-CN/config/)
# if [ -x "$(which starship)" ]; then
#     # STARSHIP_LOG=debug starship prompt
#     STARSHIP_LOG=trace starship prompt
#     # 默认配置文件 ~/.config/starship.toml。
#     export STARSHIP_CONFIG=$scripts_root_path/zsh/starship.toml # 使用 STARSHIP_CONFIG 环境变量更改默认配置文件的位置
#     # 默认情况下，Starship 会将警告和错误日志记录到文件 ~/.cache/starship/session_${STARSHIP_SESSION_KEY}.log. 
#     # 其中 session key 与您的终端实例相对应。
#     # export STARSHIP_CACHE=$scripts_root_path/zsh # 使用 STARSHIP_CACHE 环境变量来修改日志文件位置
#     eval "$(starship init zsh)"
# fi
### ---------------------------- starship ---------------------------------------

### autojump ----------------------------------------------------------- autojump
### ---------------------------- autojump ---------------------------------------

# 热键绑定----------------------------------------------------------------热键绑定
#-----------------------------------插件配置-------------------------------------



# 自定义命令-------------------------------------------------------------自定义命令
# 使用cd fd fzf 查找与切换vim文件
vimf(){
    # 加 --multi 可按tab 多选
    # 加 --cycle 选项循环
    vim $(fzf --cycle --multi --header=请选择（tab多选） --preview 'cat -n {}')
}
nvimf(){
    # 加 --multi 可按tab 多选
    # 加 --cycle 选项循环
    # nvim $(fzf --preview 'cat -n {}')
    nvim $(fzf --cycle --multi --header=请选择（tab多选）  --preview 'cat -n {}')
}
# 使用cd fd fzf 查找与切换目录
cdf(){
   # cd $(fd -p '/' -t d | fzf )
   # cd $(fd -p ’/‘ -t d | fzf --preview 'ls -alh {}')
   cd $(fd  -t  d | fzf  --cycle --header=请选择 --preview 'ls -ahl {}' )
   # 加 --cycle 选项循环
}
# 使用 cd find fzf 查找与切换目录
cdff() {
  local dir
  dir=$(find ${1:-.} -path '*/\.*' -prune \
                  -o -type d -print 2> /dev/null | fzf +m) &&
  cd "$dir"
}
# 会自动出现当前目录的 fzf，选择文件之后回车即可用默认 $EDITOR 打开文件
fe() {
  local files
  IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
  [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
}
# 使用  fzf 查找与切换tmux
# tm - create new tmux session, or switch to existing one. Works from within tmux too. (@bag-man)
# `tm` will allow you to select your tmux session via fzf.
# `tm irc` will attach to the irc session (if it exists), else it will create it.
tm() {
  [[ -n "$TMUX" ]] && change="switch-client" || change="attach-session"
  if [ $1 ]; then
    tmux $change -t "$1" 2>/dev/null || (tmux new-session -d -s $1 && tmux $change -t "$1"); return
  fi
  session=$(tmux list-sessions -F "#{session_name}" 2>/dev/null | fzf --exit-0) &&  tmux $change -t "$session" || echo "No sessions found."
}
# fs [FUZZY PATTERN] - Select selected tmux session
#   - Bypass fuzzy finder if there's only one match (--select-1)
#   - Exit if there's no match (--exit-0)
fs() {
  local session
  session=$(tmux list-sessions -F "#{session_name}" | \
    fzf --query="$1" --select-1 --exit-0) &&
  tmux switch-client -t "$session"
}

fga(){
  # 加 --cycle 选项循环
  # 加 --multi 可按tab 多选
  # git status -s | fzf --multi --preview 'bat  $( echo {} | awk -F " " '{print $2}') ' | awk -F ' ' '{print $2}'  | xargs -I {} git add {}
  git status -s | fzf  --multi --header=请选择（tab可多选） --preview 'git diff --cached $(echo {} | tr -s " " | cut -d " " -f 2)' | awk -F ' ' '{print $2}'  | xargs -I {} git add {}
  git status -s
}

lg() {
    # 检查当前是否在有效的终端中
    if [ -t 1 ] && [ -c /dev/tty ] && ( echo > /dev/tty ) 2>/dev/null; then
        # 有有效终端，直接运行 lazygit
        xecho "DEBUG" "使用直接模式运行 lazygit..."
        lazygit "$@"
    else
        # 没有有效终端，尝试使用 script 命令模拟伪终端
        xecho "DEBUG" "使用伪终端模式运行 lazygit..."
        if command -v script >/dev/null 2>&1; then
            # 尝试不同的 script 命令参数格式
            if script -q /dev/null lazygit "$@" 2>/dev/null; then
                return 0
            elif script -q -c "lazygit $*" /dev/null 2>/dev/null; then
                return 0
            else
                # 如果 script 也失败，尝试使用其他方法
                echo "script 命令失败，尝试其他方法..."
            fi
        fi
        
        # 如果所有方法都失败，尝试使用 expect 或 socat（如果可用）
        if command -v expect >/dev/null 2>&1; then
            expect -c "
                spawn lazygit $@
                interact
            "
        elif command -v socat >/dev/null 2>&1; then
            # 使用 socat 创建伪终端
            socat - EXEC:"lazygit $@",pty,setsid,ctty
        else
            xecho "ERROR" "错误: 无法找到合适的方法运行 lazygit"
            xecho "INFO" "请确保已安装 script、expect 或 socat 中的至少一个"
            return 1
        fi
    fi
}

# 下载
# 格式： m3u8dl 电影名  https://xxxxx.xxx.xx/index.m3u8
m3u8dl(){
    file_name=$1
    down_url_addr=$2
    download_file_save_path="$HOME/Downloads/$file_name.mp4"
    if [ ! -f "$download_file_save_path" ]; then
      echo "[INFO] $download_file_save_path 不存在！"
      cmdStr="ps aux | grep $file_name | grep N_m3u8DL-RE | awk '{print \$2}'"
      echo "[INFO] 命令： $cmdStr"
      ps_id=`eval $cmdStr`
      # echo "[Debug] ps_id = $ps_id "
      if [ ! -n "$ps_id" ]; then
        echo "[INFO] 不是正在下载进行中..."
        if [ -x "$(which N_m3u8DL-RE)" ]; then
            # cmdStr="$HOME/.local/bin/N_m3u8DL-RE --tmp-dir=$HOME/Downloads --save-dir=$HOME/Downloads --save-name=$file_name $down_url_addr"
            cmdStr="N_m3u8DL-RE --tmp-dir=$HOME/Downloads --save-dir=$HOME/Downloads --save-name=$file_name '$down_url_addr'"
            echo "[INFO] 命令： $cmdStr"
            # 执行命令
            # N_m3u8DL-RE --tmp-dir=$HOME/Downloads --save-dir=$HOME/Downloads --save-name=$file_name $down_url_addr
            eval $cmdStr
        else
            echo "[INFO] 没有安装或配置好 N_m3u8DL-RE "
        fi
      else
        echo "[INFO] 有进程正在下载 $file_name 中 (进程ID: $ps_id ) ."
      fi
    else
        echo "[INFO] $download_file_save_path 已经存在."
    fi
}


# 格式转化
# 格式： ts2mp4  ./少年歌行06.ts
# ffmpeg -i ./少年歌行06.ts -acodec  copy -vcodec copy  -f mp4 少年歌行06.mp4
ts2mp4(){
    if [ -x "$(which ffmpeg)" ]; then
        case "$1" in
            *.ts) filepath=$1
                  filename="$(echo $filepath |  awk -F'.ts' '{print $1}')"
                  # filenext="$(echo $filepath |  awk -F. '{print $2}')"
                  echo "[INFO] filepath $filepath"
                  echo "[INFO] filename = $filename"
                  newfilename=$filename".mp4"
                  echo "[INFO] newfilename = $newfilename"

                  # echo "[INFO] $filenext"
                  cmdStr="ffmpeg -i $filepath -acodec  copy -vcodec copy  -f mp4 $filename.mp4"
                  echo "[INFO] $cmdStr"
                  # 执行命令
                  ffmpeg -i $filepath -acodec  copy -vcodec copy  -f mp4 $newfilename
            ;;
            # *.md) glow -s dark "$1" ;;
            # *) bat --color=always --italic-text=always --style=numbers,changes,header --line-range :500 "$1" ;;
            *) echo "[INFO] 不是 .ts 文件";;
        esac
        echo "[INFO] Over ."
    else
        echo "[INFO] 没有安装或配置好 ffmpeg "
    fi
}

# 合并
# 格式： ffmpegmergets  ./诛仙01集
# 诛仙01集
# |-- 0___800000_
#     |-- 001.ts
#     |-- 002.ts
#     \-- ...
# 会生成一个tx视频文件位置txt文档然后使用 ffmpeg -f  concat -safe 0 -i ./诛仙01集-file.txt -c copy ./诛仙01集.mp4 合并
alias ffmpeg_merge_ts="${scripts_root_path}/scripts/bin/ffmpegmergets.sh"
# alias ffmpeg_merge_ts="${scripts_root_path}/scripts/ffmpegmergets.sh"
ffmpeg-merge-ts(){
  dir_path=$1
  echo "[INFO] dir_path="$dir_path
  # echo "a,b,c,d,e,f" | awk '{n=split($0, array, ",")} END{print n}'
  # echo "~/Downloads/战士第三季10" | awk '{n=split($0, array, "/")} END{print n}'
  # echo "~/Downloads/战士第三季10" | awk -F "/" '{print NF}'
  # [Linux如何统计一行数据根据分隔符分割后字段的数量? - 知乎](https://www.zhihu.com/question/533002625)
  # dir_path_length=`echo ${dir_path} |awk '{n=split($0, array, "/")} END{print n}'`
  dir_path_length=`echo ${dir_path} |awk -F "/" '{print NF}'`
  # 大于 -gt (greater than)
  # 小于 -lt (less than)
  # 大于或等于 -ge (greater than or equal)
  # 小于或等于 -le (less than or equal)
  # 不相等 -ne （not equal）
  if [[ ${dir_path_length} -ge 2 ]]; then
    # 分割数量大于等于2时
    ts_dir=`echo ${dir_path} | awk -F "/" '{print $NF}'`
    echo "[INFO] ts_dir="$ts_dir
    # 删除最后一个目录
    ts_p_dir=${dir_path%${ts_dir}*}${dir_path##*${ts_dir}}
    echo "[INFO] ts_p_dir="$ts_p_dir
    # [Linux shell字符串截取、替换、删除以及trim_shell trim_aabond的博客-CSDN博客](https://blog.csdn.net/qq_23091073/article/details/83066518)
    cd ${ts_p_dir}
    pwd
    # 执行合并ts视频文件
    # echo ${ts_dir}
    ffmpeg_merge_ts ${ts_dir}
    # 返回之前目录
    cd -
  else
    # echo  ${dir_path}
    # 执行合并ts视频文件
    ffmpeg_merge_ts ${dir_path}
  fi
}

# 批量合并文件夹下的m3u8的下载视频ts
multiple-ffmpeg-merge-ts(){
  dir_path=$1
  # echo "[INFO] dir_path = "$dir_path
  for entry in `ls $dir_path`; do
      # echo "[INFO] $entry"
      cd $dir_path
      # 执行合并ts视频文件
      ffmpeg_merge_ts $entry
      cd -
  done
}

clearLog(){
  # clear_root_dir=$1
  # 判断是否为空
  clear_root_dir=$1
  if [ ! -n "$clear_root_dir" ] ;then
    xecho "INFO" "$clear_root_dir is empty."
    xecho "INFO" "正在查找一些目录下的 *.log 文件和日志文件删除..."
    xeval "find -L $clear_root_dir -name '*.log' -print -exec rm -fr {} \;"
    xeval "rm -r $HOME/.local/bin/Log"
    # rm -r "$HOME/Library/Cache/Sublime Merge"
    # rm -r "$HOME/Library/Cache/Sublime Text"


    # Dock程序右键上的记录
    # 打开Finder，按住Option点击 前往 ，打开 资源库（~/Library/）。在搜索框中搜索：lsshare，并将搜索结果定位到“资源库”。

    # rm  "$HOME/Library/Application Support/Sublime Text/Local/*"
    # rm  "$HOME/Library/Application\ Support/Sublime\ Text/Local/Auto\ Save\ Session.sublime_session"
    # rm  "$HOME/Library/Application\ Support/Sublime\ Text/Local/Session.sublime_session"

    xeval "rm ~/Library/Application\ Support/Sublime\ Text/Local/Auto\ Save\ Session.sublime_session"
    xeval "rm ~/Library/Application\ Support/Sublime\ Text/Local/Session.sublime_session"

    # [从零开始，编写一个 HomeBrew 缓存清理脚本 - 少数派](https://sspai.com/post/65842#!)
    # clearHomebrew

    # 其他
    # - Beyond Compare 使用时间数据
    xeval "rm $HOME/Library/Application Support/Beyond Compare/registry.dat"

    # 
    # rm /var/log
    xeval "find -L $HOME/Documents -name '*.log' -print -exec rm -fr {} \;"
    xeval "find -L $HOME/Documents/XWorkSpaces -name '*.log' -print -exec rm -fr {} \;"
    xeval "find -L $HOME/Downloads -name '*.log' -print -exec rm -fr {} \;"
    xecho "INFO" "查找删除完结."
  else
    xecho "Debug" "the clear_root_dir is not empty."
    if [ -d $clear_root_dir ]; then
      xecho "INFO" "存在 $clear_root_dir 目录."
      xecho "INFO" "正在查找 $clear_root_dir 该目录下的 *.log 文件删除..."
      xeval "find -L $clear_root_dir -name '*.log' -print -exec rm -fr {} \;"
      clearDS_Store $clear_root_dir
      # echo "[INFO] 查找删除完结."
    else
      xecho "INFO" "不存在 $clear_root_dir 目录地址."
    fi
  fi
}

clearDS_Store(){
  clear_root_dir=$1
  if [ ! -n "$clear_root_dir" ] ;then
    xecho "INFO" "\$1 is empty."
    clear_root_dir="./"
  fi

  if [ -d $clear_root_dir ]; then
    xecho "INFO" "存在 $clear_root_dir 目录."
    # find ./ -maxdepth 1 -type d -empty                     # 找出当前目录下空文件夹
    # find ./ -maxdepth 1 -type d -empty -exec rm -rf {} \;  # 删除当前目录空文件夹

    # find ./ -name ".DS_Store" -depth -exec rm {} \ ;  # 
    # find ./ -maxdepth 1 -type d -empty                     # 找出当前目录下空文件夹
    # find ./ -maxdepth 1 -type d -empty -exec rm -rf {} \;  # 删除当前目录空文件夹
    # find ./ -name 'index.cdif' -exec rm -f {} \;   # 找出当前目录下index.cdif删除
    # find ./ -name "[0-9][0-9][0-9]_*.json"  -exec mv  {}  ~/Desktop/t \; # 找出当前目录下 匹配的文件移动的  ~/Desktop/t 文件夹中

    # find ./ -name "*.DS_Store" -print -exec rm -fr {} \;
    # find ./ -regex '.*\.AppleDouble\|.*\.DS_Store\|.*\.project\|.*\.settings' -print rm -fr {} \;
    # 注：.DS_Store (英文全称 Desktop Services Store)[1] 是一种由苹果公司的Mac OS X操作系统所创造的隐藏文件，目的在于存贮文件夹的自定义属性，例如文件们的图标位置或者是背景色的选择。
    xecho "INFO" "正在查找 $clear_root_dir 该目录下的 .DS_Store、._*、.~*、*.swap文件删除..."
    xeval "find -L $clear_root_dir -name '^.DS_Store' -print -exec rm -fr {} \;"
    xeval "find -L $clear_root_dir -name '^._*' -print -exec rm -fr {} \;"
    xeval "find -L $clear_root_dir -name '^.~*' -print -exec rm -fr {} \;"
    xeval "find -L $clear_root_dir -name '^～*' -print -exec rm -fr {} \;"
    xeval "find -L $clear_root_dir -name '^~*' -print -exec rm -fr {} \;"
    xeval "find -L $clear_root_dir -name '^.*.swap' -print -exec rm -fr {} \;" # 删除vim交换缓存文件
    xeval "find -L $clear_root_dir -name '*.swap' -print -exec rm -fr {} \;" # 删除vim交换缓存文件
    xecho "INFO" "查找删除完结."
  else
    xecho "INFO" "不存在 $clear_root_dir 目录."
  fi
}

#----------------------------------自定义命令-------------------------------------

# 热键绑定----------------------------------------------------------------热键绑定

alias fscp=$scripts_root_path/scripts/fzf-sshscp/scp.sh
alias fssh=$scripts_root_path/scripts/fzf-sshscp/ssh.sh
alias fsql=$scripts_root_path/scripts/fzf-sql/sql.sh
alias fcmd=$scripts_root_path/scripts/fzf-tools/cmd.sh
alias demo=$scripts_root_path/scripts/demo.sh

alias mount_ntfs=$scripts_root_path/scripts/bin/mount_ntfs.sh $@

# function mount_ntfs()
# {
#   sudo $scripts_root_path/scripts/bin/mount_ntfs.sh $@
# }


# 切换git分支
alias fgco='git checkout ${$(git branch --remote | fzf)#"origin/"}'

# merge指定分支内容

alias fgm='git merge ${$(git branch --remote | fzf)#"origin/"}'
alias gl="git log --no-merges --color --graph --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit"
# 设置git命令通用别名
alias gl='git pull'
alias gu='git push'
alias gs='git status -s'

alias r='ranger'
alias rc='source ranger'  # 退出ranger后会切换到最后停留的目录地址
alias rh='ranger_cd'

# 设置命令通用别名
alias cls='clear'
# alias la='ls -a'
if [ -x  "$(which eza)" ]; then
  # alias ll="eza --color=always --long --git --no-filesize --icons=always --no-user --no-permissions --no-time"
  alias ll="eza --color=always --long --git --no-filesize --icons=always"
else
  alias ll='ls -l'
fi
alias vi='vim'
alias javac="javac -J-Dfile.encoding=utf8"
alias grep="grep --color=auto"

## 针对文件类型设置对应的打开程序
# alias -s html=mate               # 在命令行直接输入后缀为 html 的文件名，会在 TextMate 中打开，以下类似
# alias -s rb=mate                 # 在命令行直接输入 ruby 文件，会在 TextMate 中打开
alias -s py=vim                   # 在命令行直接输入 python 文件，会用 vim 中打开
alias -s js=vim                   # 在命令行直接输入 js 文件，会用 vim 中打开
alias -s c=vim                    # 在命令行直接输入 c 文件，会用 vim 中打开
alias -s java=vim                # 在命令行直接输入 java 文件，会用 vim 中打开
alias -s txt=vim                 # 在命令行直接输入 txt 文件，会用 vim 中打开

alias -s gz='tar -xzvf'          # 在命令行直接输入 文件名，会自动解压后缀为 gz 的压缩包
alias -s tgz='tar -xzvf'         # 在命令行直接输入 文件名，会自动解压后缀为 tgz 的压缩包
alias -s zip='unzip'             # 在命令行直接输入 文件名，会自动解压后缀为 zip 的压缩包
alias -s bz2='tar -xjvf'         # 在命令行直接输入 文件名，会自动解压后缀为 bz2 的压缩包

# 按 Ctrl-P 与 Ctrl-N 在历史命令记录搜索切换。
# bindkey '^P' history-search-backward
# bindkey '^N' history-search-forward
bindkey '^P' history-substring-search-up
bindkey '^N' history-substring-search-down

# zsh的vi-mode配置
bindkey -v
# zsh下模式切换模式光标变化（插入模式光标变成 细竖条  命令模式变为粗竖条 ）
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] || [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'
  elif [[ ${KEYMAP} == main ]] || [[ ${KEYMAP} == viins ]] || [[ ${KEYMAP} = '' ]] || [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

#-----------------------------------热键绑定-------------------------------------

